'use strict';

var fs = require('fs');
var path = require('path');
var loaderUtils = require('loader-utils');

function getReplaceContent(target, reducers, getReducerName) {
    var replaceContent = '';
    var reducerKeys = [];

    getReducerName = getReducerName
        || function (filePath) {
            return filePath.replace(/[/.]/g, '_');
        };

    reducers.forEach(function (reducer) {
        var relativePath = path.relative(path.dirname(target), reducer).replace(/\\/g, '\/');
        var reducerName = getReducerName(relativePath);
        replaceContent += 'import ' + reducerName + ' from \'' + relativePath + '\';\n';
        reducerKeys.push(reducerName);
    });

    return {
        define: replaceContent,
        use: getPairsString(reducerKeys)
    };
}

function getPairsString(reducerKeys) {
    var main = '';
    reducerKeys.forEach(function (element) {
        main += element + ':' + element + ',';
    });
    return main;
}

function getFile(file, extensions) {
    extensions = extensions || [];
    if (!path.extname(file)) {

        for (var i = 0, l = extensions.length; i < l; i++) {
            var extname = extensions[i];
            var newfile = file + extname;

            if (fs.existsSync(newfile)) {
                file = newfile;
                break;
            }
        }
    }

    return file;
}

function walk(path, it, rets) {
    rets = rets || [];

    var dirList = fs.readdirSync(path);

    for (var i = 0, l = dirList.length; i < l; i++) {
        var item = dirList[i];

        if (fs.statSync(path + '/' + item).isDirectory()) {
            walk(path + '/' + item, it, rets);
        }
        else if (fs.statSync(path + '/' + item).isFile()) {
            if (item === it) {
                rets.push(path + '/' + item);
            }
        }
    }

    return rets;
}

module.exports = function (content) {
    if (this.cacheable) {
        this.cacheable();
    }

    var cwd = process.cwd();

    var query = loaderUtils.getOptions(this);
    query = Object.assign({
        placeholder: '/* __reducers-inject__ */',
        include: './src',
        extensions: ['.js', '.jsx', '.es']
    }, query);

    var include = path.join(cwd, query.include);
    var target = getFile(this.resource, query.extensions);
    var reducers = walk(include, 'redux.js');
    var replaceContent = getReplaceContent(target, reducers, query.getReducerName);

    content = content
        .replace(query.placeholder || '', replaceContent.define)
        .replace('routing', replaceContent.use + 'routing');

    return content;
};
